<template>
  <div class="api" id="api">
    <!-- 功能按钮 -->
    <div class="api_button">
      <a-button class="addButton" :disabled="creatAble" type="primary" @click="addRecord">
        <template #icon>
          <span class="iconfont icon-Add iconadd"></span>
        </template>
        新建
      </a-button>

      <div class="searchContent">
        <a-input v-model:value="apis" placeholder="请输入接口名称" style="width: 192px">
          <template #suffix>
            <i class="iconfont icon-search" @click="onSearch"></i>
          </template>
        </a-input>
      </div>
    </div>
    <!-- 表格展示部分 -->
    <baseTable :columns="columns.menusApisColumns" :dataSource="configData.records" :isSelect="true" :scroll="scroll"
      ref="searchBaseTables" :isShowPagination="isShowPagination" :showCheckDelete="showCheckDelete"
      :total="configData.total" @deleteRecord="deleteSelectedAll" @changePage="changePage">
      <template #bodyCell="{ column, record }">
        <template v-if="column.dataIndex === 'oparation'">
          <a class="eidtRecords" :class="{ disable: editAble }" @click="eidtRecord(record)">{{ record.oparation[0] }}</a>
          <a-popconfirm placement="topRight" :disabled="deleteAble" @confirm="confirmDelete(record)">
            <template #title>
              <p style="width: 197px">是否删除此接口</p>
            </template>
            <a :class="{ disable: deleteAble }">{{ record.oparation[1] }}</a>
          </a-popconfirm>
        </template>
        <template v-if="column.dataIndex === 'isRecommend'">
          <a-switch @click="switchChange(record)" size="small" v-model:checked="record.isRecommend" />
        </template>
      </template>
      <template #otherOpration>
        <a-button :style="{ 'margin-left': '8px' }" @click="deleteSelectedAll"
          :disabled="!rowSelection.length">删除</a-button>
      </template>
    </baseTable>
    <!-- 新建接口模态框 -->
    <base-modal :width="modAlProps.width" :isVisible="isVisible" :title="modAlProps.title" :buttons="buttons"
      @handleOk="buttonMessage" @handleCancle="handleCancle" class="tagword_modal">
      <template v-slot:body>
        <a-form name="advanced_search" class="ant-advanced-search-form" autoComplete="off" :model="formState"
          ref="apisFrom">
          <a-form-item :name="['apisName', 'value']" :label="formState.apisName.label" :rules="[formState.apisName.rule]">
            <a-input v-model:value="formState.apisName.value" show-count :maxlength="25" allow-clear />
          </a-form-item>
          <a-form-item :name="['apisAddress', 'value']" :label="formState.apisAddress.label"
            :rules="[formState.apisAddress.rule]">
            <a-input v-model:value="formState.apisAddress.value" allow-clear ref="apiUrl_ref" />
          </a-form-item>
          <a-form-item :name="['apisMethod', 'value']" :label="formState.apisMethod.label"
            :rules="[formState.apisMethod.rule]">
            <a-select placeholder="请选择" @change="selectChange" v-model:value="formState.apisMethod.value"
              :options="apisMethodsOptions"></a-select>
          </a-form-item>
          <a-form-item class="tag-item" :name="['apisRemark', 'value']" :label="formState.apisRemark.label"
            :rules="[formState.apisRemark.rule]">
            <a-textarea style="position: relative; margin-left: 4px" v-model:value="formState.apisRemark.value"
              placeholder="不超过200个字" show-count :maxlength="200" />
          </a-form-item>
        </a-form>
      </template>
    </base-modal>
  </div>
</template>
<script lang="ts" setup>
import { ref, reactive, computed, onMounted, nextTick, createVNode } from "vue";
import baseTable from "@/components/table/baseTable.vue";
import columns from "@/components/table/tableConfig/columnsName";
import { getTableScroll } from "@/components/table/tableConfig/table";
import baseModal from "@/components/modal/baseModal.vue";
import msgModal from "@/components/modal/modelConfig/MsGModal";
import { Modal, message, SelectProps } from "ant-design-vue";
import request from "@/api/index";
import { scrollType, modeProp } from "@/type.d";
import { checkSearchWord } from './formRuler';
import {routerPerm} from '@/utils/common';
// type
type configDataType = {
  total: number;
  size: number;
  records: any[];
};
interface dataSourceType {
  [propName: string]: any;
}
// form验证
const checkAPIurl = async (_rule: dataSourceType = {}, value: any) => {

  if (value === '') {
    return Promise.reject(`${_rule.msg1}`);
  } else {
    if (_rule.api) {
      let param = {
        requestMethod: formState.apisMethod.value,
        url: (formState.apisAddress.value).toString(),
        id: formState.id || undefined,
        name: formState.apisName.value,
      }
      let res = await request[`${_rule.api}`](param);
      if (!res) {
        return Promise.reject(`${_rule.msg2}`);
      } else {
        return Promise.resolve();
      }

    }

  }
};
//data
const creatAble = ref<boolean>(false);
const editAble = ref<boolean>(false);
const deleteAble = ref<boolean>(false);
let scroll: scrollType = reactive({ y: "", isFixed: false }); // 表单滚动设置
const isShowPagination = true; // 是否需要配分页器
const showCheckDelete = true; // 是否需要分页器中的自定义全选和删除
const apisMethodsOptions = ref<SelectProps["options"]>([
  { value: 1, label: "GET" },
  { value: 2, label: "POST" },
  { value: 3, label: "DELETE" },
  { value: 4, label: "UPDATE" },
  { value: 5, label: "PUT" },
]);
//表格数据
let configData = reactive<configDataType>({ total: 0, size: 10, records: [] });
const searchBaseTables = ref<any>(null);
let rowSelection = ref<(string | number)[]>([]);
const deleteArr = ref<(string | number)[]>([]);
const apis = ref<string>("");
// 模态框数据
const isAddOrEdit = ref<boolean>(true); //判断是新家、编辑或者批量上传来复用模态框
const isVisible = ref<boolean>(false);
const apisMethodRequest = ref<number>();
const apiUrl_ref = ref();
const modAlProps: modeProp = reactive({
  width: "M",
  title: "新建接口",
});
let datas = reactive<dataSourceType>({});

const apisFrom = ref<any>("apisFrom");
const formState = reactive<dataSourceType>({
  apisName: {
    value: "",
    rule: {
      required: true,
      validator: checkAPIurl,
      trigger: ["blur"],
      msg1: "接口名称不可为空！",
      msg2: "接口名称已存在！",
      api: "checkApiName",
      params: {},
    },
    label: "接口名称",
  },
  apisAddress: {
    value: "",
    rule: {
      required: true,
      validator: checkAPIurl,
      trigger: ["blur"],
      msg1: "接口地址不可为空！",
      msg2: "接口地址已存在！",
      api: "checkUrl_uqniue",
      params: {},
    },
    label: "接口地址",
  },
  apisMethod: {
    value: "",
    rule: {
      required: true,
      validator: checkSearchWord,
      trigger: ["blur"],
      msg1: "请求方式不可为空！",
      msg2: "请求方式已存在！",
      api: "",
      params: {},
    },
    label: "请求方式",
  },
  apisRemark: {
    value: "",
    rule: {
      required: false,
      trigger: ["blur"],
      params: {},
    },
    label: "备注",
  },
  id: "",
});
const buttons = ref<dataSourceType[]>([]); //模态框button按钮个数和文案修改
// computed
rowSelection = computed(() => {
  return searchBaseTables.value.selectedRowKeys;
});
//methods

const getMethod = (num: number) => {
  let text = "";
  switch (num) {
    case 1:
      text = "GET";
      break;
    case 2:
      text = "POST";
      break;
    case 3:
      text = "DELETE ";
      break;
    case 4:
      text = "UPDATE ";
      break;
    case 5:
      text = "PUT ";
      break;
    default:
      text = "";
  }
  return text;
};

const addRecord = async () => {
  //新加接口模态框条件修改
  //添加接口数据
  formState.apisName.value = "";
  formState.apisAddress.value = "";
  formState.apisRemark.value = "";
  formState.apisMethod.value = "";
  isVisible.value = true;
  isAddOrEdit.value = true;
  modAlProps.title = "新建接口";
  buttons.value = [
    {
      text: "保存",
      "html-type": "submit",
      keepAlive: true,
    },
    {
      text: "保存并继续新建",
      "html-type": "submit",
      keepAlive: true,
    },
  ];
};

const switchChange = (record: any) => {
  let params: dataSourceType = {
    isRecommend: record.isRecommend,
    sortNum: record.sortNum,
    word: record.word,
    id: record.key,
  };
  request
    .fetchSearchwordUpdate(params)
    .then((res: any) => {
      if (res.code == "00000 00000") {
        getRdecord();
        message.success(res.message);
      } else {
        message.error(res.message);
      }
    })
    .catch((err: any) => {
      throw new Error(err);
    });
};

const eidtRecord = async (item: dataSourceType) => {
  if(editAble.value) return
  //编辑接口数据
  const data = await request.fetchApiDetail({ id: item.id });
  isAddOrEdit.value = true;
  modAlProps.title = "编辑接口";
  buttons.value = [
    {
      text: "保存",
      "html-type": "submit",
      keepAlive: true,
    },
  ];
  formState.apisName.value = data.apiName;
  formState.apisAddress.value = data.apiUrl;
  formState.apisMethod.value = getMethod(data.requestMethod);
  formState.apisRemark.value = data.useScene;
  formState.id = data.id;
  isVisible.value = true;
};

const buttonMessage = async (msg: dataSourceType) => {
  // 新添或编辑接口调取接口

  //保存
  apisFrom.value
    .validate()
    .then(() => {
      let params: dataSourceType = {
        apiName: formState.apisName.value,
        apiUrl: formState.apisAddress.value,
        requestMethod: apisMethodRequest.value,
        useScene: formState.apisRemark.value,
        id: formState.id || 0,
      };
      let type: string = modAlProps.title.includes("编辑") ? "Edit" : "Add";

      request[type === "Edit" ? "fetchApiUpdate" : "fetchApiAdd"](params)
        .then((res: any) => {
          if (res.code == "00000 00000") {
            formState.apisName.value = "";
            formState.apisAddress.value = "";
            formState.apisRemark.value = "";
            formState.apisMethod.value = "";
            getRdecord();
            message.success(res.message);
          } else {
            message.error(res.message);
          }
        })
        .catch((err: any) => {
          throw new Error(err);
        });
      isVisible.value = msg.text == "保存" ? false : true;
    })
    .catch(() => { });
};

//选择下拉框事件
const selectChange = (e: string, options: any) => {
  apisMethodRequest.value = options.value;
  apiUrl_ref.value.focus();
  apiUrl_ref.value.blur();
};
const confirmDelete = async (item: any) => {
  // 删除单个接口
  deleteArr.value = [item.id];
  deleteRecords(deleteArr.value);
};

const deleteSelectedAll = async () => {
  //删除已选所有接口
  let keys = rowSelection.value;
  Modal.confirm(
    Object.assign({}, msgModal.confirm, {
      title: "是否批量删除选中的接口？",
      content: "",
      icon: createVNode("i", {
        class: "iconfont icon-warn warning_ICON",

      }),
      okText: "确定",
      onOk: async () => {
        await deleteRecords(keys);
        Modal.destroyAll();
      },
      onCancel() {
        Modal.destroyAll();
      },
    })
  );
};
const deleteRecords = async (keys: (string | number)[] = []) => {
  // 调接口删除接口
  await request.fetchApiDetele({ ids: keys }).then((res: any) => {
    if (res.code == "00000 00000") {
      message.success(res.message);
      getRdecord();
    } else {
      message.error(res.message);
    }
  });
};

const onSearch = async () => {
  //搜索获取数据参数配置
  getRdecord();
};
const getRdecord = async () => {
  // 获取表格数据
  const data: {} = {
    pageNumber: datas.pageNumber || 0,
    pageSize: datas.pageSize || 10,
    apiName: apis.value || "",
  };
  const telData = (await request.fetchApiList(data)) || {};
  let reqData = telData;
  let sourceData = ref<dataSourceType[]>([]);
  const records: any[] = [];
  reqData?.records?.map((item: any, index: number) => {
    sourceData = {
      ...item.middleDto,
      address: item.apiUrl,
      oparation: ["编辑", "删除"],
      methods: getMethod(item.requestMethod),
      name: item.apiName,
      remark: item.useScene,
      id: item.id,
    };
    records.push(sourceData);
  });
  configData.total = reqData.total;
  configData.size = reqData.size;

  configData.records = records;
  searchBaseTables.value.selectedRowKeys = [];

  nextTick(() => {
    scroll.y = getTableScroll(74, "api").y;
    scroll.isFixed = getTableScroll(74, "api").isFixed;
  });
};
const handleCancle = () => {
  apisFrom.value.resetFields();
  isVisible.value = false;
}
//切换分页器
const changePage = (data: { pageCurrent: any; pageSize: any }) => {
  datas = {
    pageNumber: data.pageCurrent,
    pageSize: data.pageSize,
  };
  getRdecord();
};
//onmounted
onMounted(() => {
  routerPerm().includes('creatAble') ? creatAble.value = false : creatAble.value = true;
  routerPerm().includes('editAble') ? editAble.value = false : editAble.value = true;
  routerPerm().includes('deleteAble') ? deleteAble.value = false : deleteAble.value = true;
  getRdecord();
});
</script>
<style lang="scss" scoped>
.api {
  width: 100%;
  height: calc(100% - 138px);
  padding: 24px;
  background-color: #fff;
  overflow: hidden;

  .api_button {
    padding-bottom: 24px;
    display: flex;

    .addButton {
      display: flex;
      align-items: center;
      margin-right: 8px;

      .iconadd {
        font-size: 24px;
        margin-right: 4px;
      }
    }

    .importButton {
      font-weight: 400;
      color: rgba(0, 0, 0, 0.85);
      margin-right: 8px;
    }

    .searchContent {
      margin-left: auto;
      margin-right: 0px;

      .icon-search {
        font-size: 20px;
        color: rgba(0, 0, 0, 0.45);
        position: absolute;
        right: 12px;
        top: 0px;
      }
    }
  }

  :deep(.ant-table-thead .ant-table-cell:nth-last-of-type(1)) {
    text-align: right;
    margin-right: 16px;
  }

  .eidtRecords {
    margin-right: 16px;
  }
}

.model-tip {
  margin-top: 8px;
  margin-left: 4px;
  font-size: 12px;
  font-weight: 400;
  color: rgba(0, 0, 0, 0.45);
}

.tag-item {
  margin-bottom: 0 !important;
}

::v-deep(.ant-input-textarea-show-count::after) {
  position: absolute;
  right: 12px;
  bottom: 26px;
}

::v-deep(.ant-input-number) {
  width: 136px;
  margin-left: 4px;
}

::v-deep(.ant-input-affix-wrapper) {
  width: 508px;
  margin-left: 4px;
}

::v-deep(.ant-form-item) {
  display: flex;

  .ant-form-item-label {
    flex-grow: 0;
    width: 80px;
    text-align: right;
  }
}

::v-deep(.ant-select) {
  margin-left: 4px;
  width: 508px;
}

::v-deep(.ant-form-item-control-input-content:hover) {
  .anticon-close-circle {
    display: block;
  }

  .ant-input-show-count-suffix {
    // display: none;
  }
}
</style>
